package avicit.bdp.dgs.mdm.service;

import avicit.bdp.common.base.BaseService;
import avicit.bdp.common.utils.BdpLogUtil;
import avicit.bdp.dgs.mdm.dao.MdataApplicationDao;
import avicit.bdp.dgs.mdm.dto.MDataDTO;
import avicit.bdp.dgs.mdm.dto.MdataApplicationDTO;
import avicit.bdp.dgs.mdm.dto.MdataRApplicationDTO;
import avicit.bdp.dgs.mdm.dto.TableDTO;
import avicit.bdp.dgs.mdm.utils.enums.DataFlow;
import avicit.bdp.dgs.mdm.utils.enums.EnableState;
import avicit.platform6.commons.utils.ComUtil;
import avicit.platform6.commons.utils.PojoUtil;
import avicit.platform6.core.exception.BusinessException;
import avicit.platform6.core.exception.DaoException;
import avicit.platform6.core.properties.PlatformConstant;
import avicit.platform6.core.rest.msg.QueryRespBean;
import avicit.platform6.modules.system.syslog.service.SysLogUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @金航数码科技有限责任公司
 * @作者：${tableInfo.classCreator}
 * @邮箱：${tableInfo.classMailbox}
 * @创建时间： 2023-12-06 11:02
 * @类说明：
 * @修改记录：
 */
@Service
public class MdataApplicationService extends BaseService<MdataApplicationDao, MdataApplicationDTO> {

    private static final Logger logger = LoggerFactory.getLogger(MdataApplicationService.class);

    @Autowired
    private MdataApplicationDao mdataApplicationDao;
    @Autowired
    private TableService tableService;
    @Autowired
    private MdataRApplicationService mdataRApplicationService;
    @Autowired
    private MdataInterfaceService mdataInterfaceService;

    /**
     * 分页查询
     * @param keyWords
     * @param pageNo
     * @param pageSize
     * @return
     * @throws Exception
     */
    @Transactional(readOnly = true)
    public QueryRespBean<MdataApplicationDTO> getPageList(String keyWords, Integer pageNo, Integer pageSize)
            throws Exception {
        QueryRespBean<MdataApplicationDTO> queryRespBean = new QueryRespBean<>();
        PageHelper.startPage(pageNo, pageSize);
        Page<MdataApplicationDTO> pageList = mdataApplicationDao.getPageList(keyWords);
        valueConvert(pageList.getResult());
        queryRespBean.setResult(pageList);
        BdpLogUtil.log4Query(queryRespBean);
        return queryRespBean;
    }

    private void valueConvert(List<MdataApplicationDTO> applicationList) {
        for (MdataApplicationDTO application : applicationList) {
            application.setStatusName(EnableState.getDescByCode(application.getStatus()));
            application.setDataFlowName(DataFlow.getDescByCode(application.getDataFlow()));
        }
    }

    /**
     * 新增对象
     *
     * @param dto 保存对象
     * @return String
     */
    @Transactional
    public String save(MdataApplicationDTO dto) {
        try {
            dto.setId(ComUtil.getId());
            PojoUtil.setSysProperties(dto, PlatformConstant.OpType.insert);
            dto.setStatus(0);
            this.insert(dto);

            // 写入子表数据
            saveMdata(dto.getId(), dto.getMdata());

            // 记录日志
            SysLogUtil.log4Insert(dto);
            return dto.getId();
        } catch (Exception e) {
            throw new DaoException(e.getMessage(), e);
        }
    }

    /**
     * 保存系统对应的主数据
     * @param applicationId
     * @param mdataList
     */
    private void saveMdata(String applicationId, List<String> mdataList){
        if (CollectionUtils.isNotEmpty(mdataList)) {
            for(String mdataId : mdataList){
                MdataRApplicationDTO obj = new MdataRApplicationDTO();
                obj.setId(ComUtil.getId());
                obj.setApplicationId(applicationId);
                obj.setMdataId(mdataId);
                mdataRApplicationService.insert(obj);
            }
        }
    }

    /**
     * 修改对象部分字段
     *
     * @param dto 修改对象
     * @return int
     */
    @Transactional
    public int update(MdataApplicationDTO dto) {
        try {
            int count = this.updateByPrimaryKey(getUpdateDto(dto));
            if (count == 0) {
                throw new DaoException("数据失效，请重新更新");
            }

            mdataRApplicationService.deleteMdataByApplicationId(dto.getId());
            // 写入子表数据
            saveMdata(dto.getId(), dto.getMdata());

            return count;
        } catch (Exception e) {
            throw new DaoException(e.getMessage(), e);
        }
    }

    /**
     * 通过主键查询单条记录
     *
     * @param id 主键id
     */
    @Transactional(readOnly = true)
    public MdataApplicationDTO queryById(String id) {
        try {
            MdataApplicationDTO dto = this.selectByPrimaryKey(id);
            // 记录日志
            if (dto != null) {
                SysLogUtil.log4Query(dto);
                dto.setStatusName(EnableState.getDescByCode(dto.getStatus()));
                dto.setDataFlowName(DataFlow.getDescByCode(dto.getDataFlow()));
                List<MdataRApplicationDTO> mdataList = queryMDataListByAppId(id);
                List<String> mdataIds = mdataList.stream().map(MdataRApplicationDTO::getMdataId).collect(Collectors.toList());
                dto.setMdata(mdataIds);
            }
            return dto;
        } catch (Exception e) {
            throw new DaoException(e.getMessage(), e);
        }
    }

    /**
     * 删除
     */
    @Transactional
    public void deleteById(MdataApplicationDTO dto){
        if (StringUtils.isEmpty(dto.getId())) {
            throw new BusinessException("id不能为空");
        }

        String[] idArr = dto.getId().split(",");
        for(String id : idArr){
            // 验证是否被使用
            long num = mdataInterfaceService.selectCountByAppId(id);
            if(num > 0){
                MdataApplicationDTO oldDTO = this.selectByPrimaryKey(id);
                throw new BusinessException("系统名称为【"+oldDTO.getName()+"】的系统被接口引用，不能删除");
            }
            mdataRApplicationService.deleteMdataByApplicationId(id);
            this.deleteByPrimaryKey(id);
        }
    }

    /**
     * 内部方法，获取修改的dto对象
     *
     * @param dto
     * @return
     */
    private MdataApplicationDTO getUpdateDto(MdataApplicationDTO dto) {
        MdataApplicationDTO oldDTO = this.selectByPrimaryKey(dto.getId());
        if (oldDTO == null) {
            throw new DaoException("数据不存在");
        }
        //记录日志
        SysLogUtil.log4Update(dto, oldDTO);
        PojoUtil.setSysProperties(dto, PlatformConstant.OpType.update);
        PojoUtil.copyProperties(oldDTO, dto, true);
        return oldDTO;
    }

    /**
     * 启用停用
     */
    @Transactional
    public void updateStatus(MdataApplicationDTO dto){
        if (StringUtils.isEmpty(dto.getId())) {
            throw new BusinessException("id不能为空");
        }

        String[] idArr = dto.getId().split(",");
        List<String> idList = Arrays.asList(idArr);
        mdataApplicationDao.updateStatus(idList, dto.getStatus());
    }

    /**
     * 查询系统列表
     *
     */
    @Transactional(readOnly = true)
    public List<MdataApplicationDTO> queryList() {
        MdataApplicationDTO dto = new MdataApplicationDTO();
        dto.setStatus(EnableState.ENABLE.getCode());
        return this.selectList(dto);
    }

    /**
     * 查询所有系统列表
     *
     */
    @Transactional(readOnly = true)
    public List<MdataApplicationDTO> queryAllList() {
        return this.selectListAll();
    }

    /**
     * 查询主数据列表
     *
     */
    @Transactional(readOnly = true)
    public List<MDataDTO> queryMDataList() {
        List<MDataDTO> list = new ArrayList<>();
        TableDTO dto = new TableDTO();
        // 状态，0：草稿、1：审核中、2：已发布、3：已驳回
        dto.setStatus(2);
        List<TableDTO> tableList = tableService.selectListAll(dto);
        if (CollectionUtils.isNotEmpty(tableList)) {
            for(TableDTO obj : tableList){
                MDataDTO mdata = new MDataDTO();
                mdata.setMdataId(obj.getId());
                mdata.setMdataName(obj.getName());
                list.add(mdata);
            }
        }
        return list;
    }

    /**
     * 根据系统ID查询主数据列表
     *
     */
    @Transactional(readOnly = true)
    public List<MdataRApplicationDTO> queryMDataListByAppId(String applicationId) {
        return mdataRApplicationService.queryMDataListByAppId(applicationId);
    }

}
